/**
 * 文件管理模块
 * 负责处理文件的打开、保存等操作
 * 使用 Tauri API 进行文件系统交互
 */
// 使用动态导入来避免模块解析错误
let dialogAPI = null;
let fsAPI = null;

// 初始化 Tauri API
async function initTauriAPIs() {
  if (typeof window !== 'undefined' && window.__TAURI__) {
    try {
      // 使用 Tauri 2.x 的正确导入方式
      const dialog = window.__TAURI_PLUGIN_DIALOG__;
      const fs = window.__TAURI_PLUGIN_FS__;
      
      if (dialog && fs) {
        dialogAPI = dialog;
        fsAPI = fs;
      } else {
        console.error('Tauri plugins not available');
      }
    } catch (error) {
      console.error('Failed to load Tauri APIs:', error);
    }
  }
}

class FileManager {
  constructor() {
    this.supportedFormats = [
      {
        name: 'HTML 文件',
        extensions: ['html', 'htm']
      },
      {
        name: '文本文件',
        extensions: ['txt']
      },
      {
        name: 'Markdown 文件',
        extensions: ['md', 'markdown']
      },
      {
        name: '所有文件',
        extensions: ['*']
      }
    ];
    // 初始化 Tauri APIs
    initTauriAPIs();
  }

  /**
   * 打开文件对话框并读取文件
   * @returns {Promise<{content: string, filePath: string}|null>} 文件内容和路径
   */
  async openFile() {
    try {
      // 确保 API 已初始化
      if (!dialogAPI || !fsAPI) {
        await initTauriAPIs();
      }
      
      if (!dialogAPI || !fsAPI) {
        throw new Error('Tauri APIs not available');
      }

      // 打开文件选择对话框 - 简化参数避免卡死
      const filePath = await dialogAPI.open({
        multiple: false
      });

      if (!filePath) {
        return null; // 用户取消了选择
      }

      // 检查文件大小并优化读取
      try {
        // 先尝试获取文件信息
        const fileInfo = await this.getFileInfo(filePath);
        
        // 如果文件过大（超过10MB），给出警告
        if (fileInfo && fileInfo.size > 10 * 1024 * 1024) {
          const shouldContinue = await this.confirmLargeFile(fileInfo.size);
          if (!shouldContinue) {
            return null;
          }
        }
        
        // 读取文件内容
        console.log('开始读取文件:', filePath);
        const content = await fsAPI.readTextFile(filePath);
        
        console.log('文件已读取:', filePath, '大小:', content.length, '字符');
        return {
          content,
          filePath
        };
      } catch (readError) {
        console.error('读取文件内容失败:', readError);
        throw new Error(`读取文件失败: ${readError.message}`);
      }
    } catch (error) {
      console.error('打开文件失败:', error);
      throw new Error(`无法打开文件: ${error.message}`);
    }
  }

  /**
   * 保存文件
   * @param {string} filePath - 文件路径
   * @param {string} content - 文件内容
   * @returns {Promise<boolean>} 是否保存成功
   */
  async saveFile(filePath, content) {
    try {
      // 确保 API 已初始化
      if (!fsAPI) {
        await initTauriAPIs();
      }
      
      if (!fsAPI) {
        throw new Error('Tauri FS API not available');
      }
      
      await fsAPI.writeTextFile(filePath, content);
      console.log('文件已保存:', filePath);
      return true;
    } catch (error) {
      console.error('保存文件失败:', error);
      throw new Error(`无法保存文件: ${error.message}`);
    }
  }

  /**
   * 另存为文件
   * @param {string} content - 文件内容
   * @param {string} defaultName - 默认文件名
   * @returns {Promise<{filePath: string}|null>} 保存的文件路径
   */
  async saveFileAs(content, defaultName = '未命名文档.html') {
    try {
      // 确保 API 已初始化
      if (!dialogAPI || !fsAPI) {
        await initTauriAPIs();
      }
      
      if (!dialogAPI || !fsAPI) {
        throw new Error('Tauri APIs not available');
      }
      
      // 打开保存对话框
      const filePath = await dialogAPI.save({
        title: '另存为',
        defaultPath: defaultName,
        filters: this.supportedFormats
      });

      if (!filePath) {
        return null; // 用户取消了保存
      }

      // 保存文件
      await fsAPI.writeTextFile(filePath, content);
      
      console.log('文件已另存为:', filePath);
      return {
        filePath
      };
    } catch (error) {
      console.error('另存为失败:', error);
      throw new Error(`无法保存文件: ${error.message}`);
    }
  }

  /**
   * 获取文件信息
   * @param {string} filePath - 文件路径
   * @returns {Promise<Object|null>} 文件信息对象
   */
  async getFileInfo(filePath) {
    try {
      if (!fsAPI) {
        await initTauriAPIs();
      }
      
      if (!fsAPI || !fsAPI.stat) {
        // 如果没有stat API，返回null
        return null;
      }
      
      const stats = await fsAPI.stat(filePath);
      return stats;
    } catch (error) {
      console.warn('获取文件信息失败:', error);
      return null;
    }
  }

  /**
   * 确认是否打开大文件
   * @param {number} fileSize - 文件大小（字节）
   * @returns {Promise<boolean>} 是否继续打开
   */
  async confirmLargeFile(fileSize) {
    try {
      const sizeMB = (fileSize / (1024 * 1024)).toFixed(2);
      const message = `文件大小为 ${sizeMB} MB，可能会影响性能。是否继续打开？`;
      
      if (window.__TAURI_PLUGIN_DIALOG__) {
        return await window.__TAURI_PLUGIN_DIALOG__.confirm(message, {
          title: '大文件警告',
          kind: 'warning'
        });
      } else {
        return confirm(message);
      }
    } catch (error) {
      console.error('显示大文件确认对话框失败:', error);
      return true; // 默认允许打开
    }
  }

  /**
   * 检查文件是否存在
   * @param {string} filePath - 文件路径
   * @returns {Promise<boolean>} 文件是否存在
   */
  async fileExists(filePath) {
    try {
      const fileInfo = await this.getFileInfo(filePath);
      return fileInfo !== null;
    } catch (error) {
      console.error('检查文件存在性失败:', error);
      return false;
    }
  }

  /**
   * 获取文件扩展名
   * @param {string} filePath - 文件路径
   * @returns {string} 文件扩展名
   */
  getFileExtension(filePath) {
    if (!filePath) return '';
    const lastDot = filePath.lastIndexOf('.');
    return lastDot > -1 ? filePath.substring(lastDot + 1).toLowerCase() : '';
  }

  /**
   * 根据文件扩展名判断文件类型
   * @param {string} filePath - 文件路径
   * @returns {string} 文件类型
   */
  getFileType(filePath) {
    const extension = this.getFileExtension(filePath);
    
    switch (extension) {
      case 'html':
      case 'htm':
        return 'html';
      case 'md':
      case 'markdown':
        return 'markdown';
      case 'txt':
        return 'text';
      default:
        return 'text';
    }
  }

  /**
   * 将内容转换为指定格式
   * @param {string} content - 原始内容
   * @param {string} fromFormat - 源格式
   * @param {string} toFormat - 目标格式
   * @returns {string} 转换后的内容
   */
  convertContent(content, fromFormat, toFormat) {
    if (fromFormat === toFormat) {
      return content;
    }

    // 简单的格式转换
    switch (`${fromFormat}->${toFormat}`) {
      case 'html->text':
        // 移除 HTML 标签
        return content.replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ');
      
      case 'text->html':
        // 将换行转换为 <br> 标签
        return content.replace(/\n/g, '<br>');
      
      case 'html->markdown':
        // 简单的 HTML 到 Markdown 转换
        return content
          .replace(/<h([1-6])>/g, (match, level) => '#'.repeat(parseInt(level)) + ' ')
          .replace(/<\/h[1-6]>/g, '\n\n')
          .replace(/<strong>/g, '**')
          .replace(/<\/strong>/g, '**')
          .replace(/<em>/g, '*')
          .replace(/<\/em>/g, '*')
          .replace(/<br\s*\/?>/g, '\n')
          .replace(/<p>/g, '')
          .replace(/<\/p>/g, '\n\n')
          .replace(/<[^>]*>/g, '');
      
      case 'markdown->html':
        // 简单的 Markdown 到 HTML 转换
        return content
          .replace(/^### (.*$)/gim, '<h3>$1</h3>')
          .replace(/^## (.*$)/gim, '<h2>$1</h2>')
          .replace(/^# (.*$)/gim, '<h1>$1</h1>')
          .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
          .replace(/\*(.*?)\*/g, '<em>$1</em>')
          .replace(/\n/g, '<br>');
      
      default:
        return content;
    }
  }

  /**
   * 导出文件为不同格式
   * @param {string} content - 文件内容
   * @param {string} format - 导出格式
   * @param {string} fileName - 文件名
   * @returns {Promise<{filePath: string}|null>} 导出的文件路径
   */
  async exportFile(content, format, fileName) {
    try {
      const filters = [];
      let defaultName = fileName || '导出文档';
      
      switch (format) {
        case 'html':
          filters.push({ name: 'HTML 文件', extensions: ['html'] });
          defaultName += '.html';
          break;
        case 'text':
          filters.push({ name: '文本文件', extensions: ['txt'] });
          defaultName += '.txt';
          content = this.convertContent(content, 'html', 'text');
          break;
        case 'markdown':
          filters.push({ name: 'Markdown 文件', extensions: ['md'] });
          defaultName += '.md';
          content = this.convertContent(content, 'html', 'markdown');
          break;
        default:
          throw new Error(`不支持的导出格式: ${format}`);
      }

      const filePath = await save({
        title: `导出为 ${format.toUpperCase()}`,
        defaultPath: defaultName,
        filters
      });

      if (!filePath) {
        return null;
      }

      await writeTextFile(filePath, content);
      
      console.log('文件已导出:', filePath);
      return { filePath };
    } catch (error) {
      console.error('导出文件失败:', error);
      throw new Error(`无法导出文件: ${error.message}`);
    }
  }

  /**
   * 获取最近打开的文件列表
   * @returns {Array<string>} 最近文件列表
   */
  getRecentFiles() {
    try {
      const recent = localStorage.getItem('editbook_recent_files');
      return recent ? JSON.parse(recent) : [];
    } catch {
      return [];
    }
  }

  /**
   * 添加文件到最近打开列表
   * @param {string} filePath - 文件路径
   */
  addToRecentFiles(filePath) {
    try {
      let recentFiles = this.getRecentFiles();
      
      // 移除已存在的相同路径
      recentFiles = recentFiles.filter(path => path !== filePath);
      
      // 添加到开头
      recentFiles.unshift(filePath);
      
      // 限制最多保存 10 个
      recentFiles = recentFiles.slice(0, 10);
      
      localStorage.setItem('editbook_recent_files', JSON.stringify(recentFiles));
    } catch (error) {
      console.error('保存最近文件列表失败:', error);
    }
  }

  /**
   * 清空最近文件列表
   */
  clearRecentFiles() {
    try {
      localStorage.removeItem('editbook_recent_files');
    } catch (error) {
      console.error('清空最近文件列表失败:', error);
    }
  }
}

export default FileManager;